本文章的內容僅限學術及研究用途,請勿進行任何違法行為,否則後果自負。
進行字典檔攻擊的流程為:
準備的金鑰字典數量越多,進行攻擊所需的時間可能會越久,程式碼如下:
// 在測試網頁的開發者工具中執行 https://taichunmin.idv.tw/chameleon-ultra.js/test.html
await (async (ultra) => {
// 載入一些 JS 函式庫
const _ = (await import('https://cdn.jsdelivr.net/npm/lodash@4.17.21/+esm'))?.default
const { Buffer, Mf1KeyType } = await import('https://cdn.jsdelivr.net/npm/chameleon-ultra.js@0/+esm')
// 這是網友整理的字典檔網址
const dicUrls = [
'https://raw.githubusercontent.com/ikarus23/MifareClassicTool/master/Mifare%20Classic%20Tool/app/src/main/assets/key-files/extended-std.keys',
'https://raw.githubusercontent.com/RfidResearchGroup/proxmark3/master/client/dictionaries/mfc_default_keys.dic',
]
// 取得字典檔的內容,然後解析內容後放到一個 Set 裡面去除重複
const keySet = new Set(_.flatMap(await Promise.all(_.map(dicUrls, async url => {
// 透過網址取得字典檔的內容
const resp = await fetch(url, { method: 'GET' })
let text = _.trim(await resp.text())
// 取代換行符號、去除空白行及註解
text = text.replaceAll(/[\r\n]+/g, '\n').replaceAll(/#[^\n]+\n/g, '')
return text.split('\n') // 透過換行符號分割字串
}))))
// 取出 Set 裡面的金鑰,然後轉成 Buffer 陣列
const keys = _.map([...keySet.values()], key => Buffer.from(key, 'hex'))
console.log(`keys.length = ${keys.length}`) // 顯示字典檔的金鑰數量
const startedAt = Date.now() // 記錄開始時間
// 提供字典檔、最大的區段數量、以及每次處理的金鑰數量來測試 M1 卡的金鑰
const sectorKeys = await ultra.mf1CheckKeysOfSectors({ keys, maxSectors: 16, chunkSize: 20 })
const elapsed = Date.now() - startedAt // 計算經過的時間
console.log(`elapsed: ${elapsed} ms`)
// 顯示每個區段的金鑰
const bufToHex = buf => buf?.toString('hex').toUpperCase()
for (let i = 0; i < 16; i++) {
console.log(`Sector ${i}: A = ${bufToHex(sectorKeys[2 * i])}, B = ${bufToHex(sectorKeys[2 * i + 1])}`)
}
})(vm.ultra)
程式碼的執行結果如下: